


#include "Public.h"

//-----------时钟控制寄存器(RCC_CR)-------------------
#define HSION        (u32)1  // 内部高速时钟使能
#define HSIRDY       (u32)2  // 内部高速时钟就绪标志
// [4:0] 晶振调整
#define HSITRIM      (u32)0<<3  //

//[7:0]
#define HSICAL       (u32)0<<8  // 内部高速时钟校准

#define HSEON        (u32)1<<16
#define HSERDY       (u32)1<<17
#define HSEBYP       (u32)1<<18
#define CSSON        (u32)1<<19 // 时钟安全系统使能

#define PLLON        (u32)1<<24 //PLL使能
#define PLLRDY       (u32)1<<25 //PLL使能

//-------时钟配置寄存器(RCC_CFGR)--------------------
#define _SW_HSI        (u32)3  //系统时钟切换 00-> HSI作为系统时钟； 取反
#define  SW_HSE        (u32)1  //系统时钟切换 01-> HSE作为系统时钟；
#define  SW_PLL        (u32)2  //系统时钟切换 10-> PLL输出作为系统时钟；

#define  SW_HSI_STA    (u32)3<<2 //HSI作为系统时钟； 00-> HSI作为系统时钟； 取反
#define  SW_HSE_STA    (u32)1<<2 //HSE作为系统时钟；01-> HSE作为系统时钟
#define  SW_PLL_STA    (u32)2<<2 //PLL输出作为系统时钟；10-> PLL输出作为系统时钟
// AHB预分频 [3:0] (AHB Prescaler)
#define _AHB_SYSCLK_1  (u32)(15)<<4 //AHB预分频 SYSCLK 1分频   0000
#define  AHB_SYSCLK_2  (u32)(8+0)<<4 //AHB预分频 SYSCLK 2分频  1000
#define  AHB_SYSCLK_4  (u32)(8+1)<<4 //AHB预分频 SYSCLK 4分频  1001
#define  AHB_SYSCLK_8  (u32)(8+2)<<4 //AHB预分频 SYSCLK 8分频  1010
#define  AHB_SYSCLK_16 (u32)(8+3)<<4 //AHB预分频 SYSCLK 16分频 
#define  AHB_SYSCLK_32 (u32)(8+4)<<4 //AHB预分频 SYSCLK 32分频 

// 低速APB预分频 (APB1)[2:0] 警告：软件必须保证APB1时钟频率不超过36MHz。
#define _APB1_HCLK_1   (uint32_t)(7)<<8   //低速APB预分频(APB1) HCLK 1分频  000
#define  APB1_HCLK_2   (uint32_t)(4+0)<<8 //低速APB预分频(APB1) HCLK 2分频  
#define  APB1_HCLK_4   (uint32_t)(4+1)<<8 //低速APB预分频(APB1) HCLK 4分频  
#define  APB1_HCLK_8   (uint32_t)(4+2)<<8 //低速APB预分频(APB1) HCLK 8分频  
#define  APB1_HCLK_16  (uint32_t)(4+3)<<8 //低速APB预分频(APB1) HCLK 16分频  
// 高速APB预分频(APB2) [2:0]
#define _APB2_HCLK_1   (uint32_t)(7)<<11   //高速APB预分频(APB2)  HCLK 1分频  000
#define  APB2_HCLK_2   (uint32_t)(4+0)<<11 //高速APB预分频(APB2)  HCLK 2分频  
#define  APB2_HCLK_4   (uint32_t)(4+1)<<11 //高速APB预分频(APB2)  HCLK 4分频  
#define  APB2_HCLK_8   (uint32_t)(4+2)<<11 //高速APB预分频(APB2)  HCLK 8分频  
#define  APB2_HCLK_16  (uint32_t)(4+3)<<11 //高速APB预分频(APB2)  HCLK 16分频  
// ADC预分频 (ADC prescaler)[1:0]
#define _ADC_PCLK2_2   (uint32_t)3<<14 //PCLK2 2分频后作为ADC时钟 00
#define  ADC_PCLK2_4   (uint32_t)1<<14 //PCLK2 4分频后作为ADC时钟
#define  ADC_PCLK2_6   (uint32_t)2<<14 //PCLK2 6分频后作为ADC时钟
#define  ADC_PCLK2_8   (uint32_t)3<<14 //PCLK2 8分频后作为ADC时钟
// PLLSRC： PLL输入时钟源  
#define  PLLSR_HSE     (uint32_t)1<<16 //0： HSI振荡器时钟经2分频后作为PLL输入时钟,1： HSE时钟作为PLL输入时钟。
//HSE分频器作为PLL输入
#define  PLLXTPRE_HSE  (uint32_t)1<<17 //0： HSE不分频.. 1： HSE 2分频  
// PLLMUL： PLL倍频系数 [3:0]
#define  PLLMUL_2      (uint32_t)0<<18  // PLL 2倍频输出,PLL的输出频率不能超过72MHz
#define  PLLMUL_3      (uint32_t)1<<18  // PLL 3倍频输出,PLL的输出频率不能超过72MHz
#define  PLLMUL_4      (uint32_t)2<<18  // PLL 4倍频输出,PLL的输出频率不能超过72MHz
 
#define USBPRE         (uint32_t)1<<22 // PLL 16倍频输出,PLL的输出频率不能超过72MHz

//MCO[3:0]微控制器时钟输出 
#define MCO_NOP         (uint32_t)0<<24 // 没有时钟输出
#define MCO_SYSCLK      (uint32_t)4<<24 // 系统时钟(SYSCLK)输出；
#define MCO_HSI         (uint32_t)4<<24 // 内部RC振荡器时钟(HSI)输出
#define MCO_PLL         (uint32_t)4<<24 // PLL时钟2分频后输出




//==================================================================



void System_Hsi_Colk(void)
{

  //复位 RCC->CFGR 为 00；
  /*   
                                 开启PLLON：
                          HSI---------|                                             
              ( 2~16倍)               |            （AHB分频）    
   { HSI/2}* PLLMUL[3:0]--->PLLCLK-->(+)--->sysclk / HPRE[3:0]-->hclk
   

   hclk/APB1[2:0] --->PCLK1 -->TIMx CLK
   
   hclk/APB2[2:0] --->PCLK2 -->TIM1 CLK
                      PCLK2/(ADC prescaler)[1:0]  ----ADC clk                           
                                                        
 */
   RCC->CIR  =  1<<23 | 1<<20 | 15<<19; //清相应的中断

   RCC->CR  |=  (uint32_t)0X01;           // HSION;
   while((RCC->CR & (uint32_t)0X02)==0); // HSIRDY:等待 内部高速时钟就绪

 //  if (HSIStartUpStatus == RCC_CR_HSIRDY) 
 //  {  
 //    FLASH_SetLatency(FLASH_Latency_2);
 //  }
 //  FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
   
    //- Enable Prefetch Buffer and set Flash Latency 
   FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;
   //-----AHB预分频-------
   RCC->CFGR |=(uint32_t)(0+0)<<4;  // HPRE[3:0]： AHB预分频
                               // (u32)(0+0)<<4: SYSCLK 不分频
                               // (u32)(8+0)<<4：SYSCLK 2分频
                               // (u32)(8+1)<<4：SYSCLK 4分频
//-----低速APB1分频-------
   RCC->CFGR |=(uint32_t)(0+0)<<8;  // 低速APB1[2:0] 
                               // (u32)(0+0)<<8  低速APB预分频(APB1) HCLK 不分频
                               // (u32)(4+0)<<8  低速APB预分频(APB1) HCLK 2分频
                               // (u32)(4+1)<<8  低速APB预分频(APB1) HCLK 4分频   
//-----高速APB2预分频-------   
   RCC->CFGR |=(uint32_t)(0+0)<<11; // 高速APB2[2:0]  
                               // (u32)(0+0)<<11 高速APB预分频(APB2) HCLK不分频
                               // (u32)(4+0)<<11 高速APB预分频(APB2) HCLK 2分频
                               // (u32)(4+1)<<11 高速APB预分频(APB2) HCLK 4分频
//----PLL倍频系数-----
   //(12-2)表示12倍频
   RCC->CFGR |=(uint32_t)(12-2)<<18; // PLLMUL： PLL倍频系数 [3:0]   由软件设置来确定PLL倍频系数。只有在PLL关闭的情况下才可被写入。
                               // (u32)(2-2)<<18 PLL 2倍频输出 
                               // (u32)(3-2)<<18 PLL 3倍频输出 
                               // (u32)(4-2)<<18 PLL 4倍频输出 
                               // (u32)(5-2)<<18 PLL 5倍频输出 
                               // (u32)(6-2)<<18 PLL 6倍频输出 
                               // (u32)(7-2)<<18 PLL 7倍频输出 
                               // (u32)(8-2)<<18 PLL 8倍频输出 
                               // (u32)(9-2)<<18 PLL 9倍频输出 
   
   RCC->CFGR &= ~((uint32_t)1<<16); //PLLSRC-》 0: HSI振荡器时钟经2分频后作为PLL输入时钟, 1: HSE时钟作为PLL输入时钟。
  
   RCC->CFGR &= ~((uint32_t)3<<14); // ADC预分频 (ADC prescaler)[1:0]   
                               // 00：PCLK2 2分频后作为ADC时钟 

  // RCC->CFGR &= ~((uint32_t)3);   
                               // [1:0]  
                               // 00：HSI作为系统时钟
                               // 01: SW_HSE
                               // 10: SW_PLL  PLL输出作为系统时钟；
   
   RCC->CFGR |= (uint32_t)2;         // PLL作为输出时钟
   while(RCC->CFGR & SW_PLL_STA);//
   
   RCC->CR   |= (uint32_t)1<<24;      //PLLON; PLL使能    开PLL
   while( RCC->CR & PLLRDY );  //

}


void SystemClock_Init(void)
{

  RCC_DeInit(); //RCC 系统复位
   
 //  SystemInit();      //用于外部 48mhz 高速时钟

   System_Hsi_Colk(); //用于内部高速时钟
   
   RCC_HCLKConfig(RCC_SYSCLK_Div1);     //设置AHB时钟不分频
  //  RCC_PCLK2Config(RCC_HCLK_Div1);   //设置APB2时钟不分频
  //  RCC_PCLK1Config(RCC_HCLK_Div2);   //设置APB1时钟二分频
  //  RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC时钟六分频 
  RCC_LSICmd(ENABLE);   
   
   
}
